use rhai::CustomType;
use rhai::Dynamic;
use rhai::Map;
use rhai::TypeBuilder;
use rhai::INT;

use crate::model::indicators::macd::MACD;
use crate::model::indicators::rsi::RSI;
use crate::model::indicators::IndicatorActionWrap;
use crate::model::kline::Kline;

impl CustomType for MACD {
    fn build(mut builder: TypeBuilder<Self>) {
        builder
            .with_name("MACD")
            // Register getters for each field you want to expose
            .with_get("signal0", |o: &mut MACD| Dynamic::from(
                match &o.signal0{
                    Some(v) => v.clone(),
                    None => IndicatorActionWrap{..Default::default()},
                }            
            ))
            .with_get("signal1", |o: &mut MACD| Dynamic::from(
                match &o.signal1{
                    Some(v) => v.clone(),
                    None => IndicatorActionWrap{..Default::default()},
                }    
            ))
            .with_get("macd", |o: &mut MACD| Dynamic::from(o.macd))
            .with_get("signal", |o: &mut MACD| Dynamic::from(o.signal))
            .with_get("bar", |o: &mut MACD| Dynamic::from(o.bar))
            // Continue for other fields...
            ;
    }
}

impl CustomType for RSI {
    fn build(mut builder: TypeBuilder<Self>) {
        builder
            .with_name("RSI")
            // Register getters for each field you want to expose
            .with_get("signal0", |o: &mut RSI| Dynamic::from(
                match &o.signal0{
                    Some(v) => v.clone(),
                    None => IndicatorActionWrap{..Default::default()},
                }    
            ))
            .with_get("signal1", |o: &mut RSI| Dynamic::from( 
                match &o.signal1{
                    Some(v) => v.clone(),
                    None => IndicatorActionWrap{..Default::default()},
                }    
            ))
            .with_get("upper", |o: &mut RSI| Dynamic::from(o.upper))
            .with_get("main", |o: &mut RSI| Dynamic::from(o.main))
            .with_get("lower", |o: &mut RSI| Dynamic::from(o.lower))
            // Continue for other fields...
            ;
    }
}

impl CustomType for Kline {
    fn build(mut builder: TypeBuilder<Self>) {
        // let kline = Kline{..Default::default()};
        // let aa = kline.macd.clone().is_some().then(|| kline.macd.clone().unwrap());

        builder
            .with_name("Kline")
            // Register getters for each field you want to expose
            .with_get("id", |o: &mut Kline| match &o.id{
                Some(t) => Dynamic::from(t.id.to_raw()),
                None => Dynamic::from(""),
            }
        )
            .with_get("open", |o: &mut Kline| Dynamic::from(o.open))
            .with_get("high", |o: &mut Kline| Dynamic::from(o.high))
            .with_get("low", |o: &mut Kline| Dynamic::from(o.low))
            .with_get("close", |o: &mut Kline| Dynamic::from(o.close))
            .with_get("volume", |o: &mut Kline| Dynamic::from(o.volume))
            // .with_get("macd", |o: &mut Kline| Dynamic::from(o.macd.clone().unwrap_or_default()))
            // .with_get("rsi", |o: &mut Kline| Dynamic::from(o.rsi.clone().unwrap_or_default()))
            // Continue for other fields...
            ;
    }
}

impl CustomType for IndicatorActionWrap {
    fn build(mut builder: TypeBuilder<Self>) {
        builder
            .with_name("IndicatorActionWrap")
            // Register getters for each field you want to expose
            .with_get("buy", |o: &mut IndicatorActionWrap| Dynamic::from(o.buy))
            .with_get("sell", |o: &mut IndicatorActionWrap| Dynamic::from(o.sell));
    }
}
